package org.kwisatz.proxybot;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server extends Thread
{
	public final static Logger LOGGER=Logger.getLogger(Server.class.getName());
	private int port;
	private List<Connection> connections = new ArrayList<Connection>();
	private Map<String, Filter> filters = new HashMap();
	
	public Server()
	{
		this(3128);
	}

	public Server(int port)
	{
		this.port = port;
	}

	public void remove(Connection c) {
		connections.remove(c);
	}

	public void run() {
		try {
			ServerSocket ss = new ServerSocket(
				port, 50, InetAddress.getByName("localhost"));
			while (true) {
				Socket s;
				try
				{
					s = ss.accept();
					LOGGER.info("Connection from " + s);
					Connection c = new Connection(this, s);
					for(Filter f:filters.values())
						c.add(f.getClass());
					connections.add(c);
				} catch (Exception ex) {
					LOGGER.log(Level.SEVERE, null, ex);
				}
			}
		} catch (IOException ex) {
			LOGGER.log(Level.SEVERE, null, ex);
		}
	}

	public List<Connection> getConnections()
	{	
		return Collections.unmodifiableList(connections);
	}

	public void readd(Class<? extends Filter> filterClass)
		throws InstantiationException, IllegalAccessException
	{
		remove(filterClass);
		add(filterClass);
	}

	public void add(Class<? extends Filter> filterClass)
		throws InstantiationException, IllegalAccessException
	{
		Filter t = filterClass.newInstance();
		filters.put(t.getID(), t);
		for(Connection c: connections)
			c.add(filterClass);
	}

	public void remove(Class<? extends Filter> filterClass)
		throws InstantiationException, IllegalAccessException
	{
		Filter t = filterClass.newInstance();
		remove(t.getID());
	}
	
	public void remove(String id)
	{
		filters.remove(id);
		for(Connection c: connections)
			c.remove(id);
	}
}
